home *** CD-ROM | disk | FTP | other *** search
- /* National Institute of Standards and Technology (NIST)
- /* National Computer System Laboratory (NCSL)
- /* Office Systems Engineering (OSE) Group
- /* ********************************************************************
- /* D I S C L A I M E R
- /* (March 8, 1989)
- /*
- /* There is no warranty for the NIST NCSL OSE SGML parser and/or the NIST
- /* NCSL OSE SGML parser validation suite. If the SGML parser and/or
- /* validation suite is modified by someone else and passed on, NIST wants
- /* the parser's recipients to know that what they have is not what NIST
- /* distributed, so that any problems introduced by others will not
- /* reflect on our reputation.
- /*
- /* Policies
- /*
- /* 1. Anyone may copy and distribute verbatim copies of the SGML source
- /* code as received in any medium.
- /*
- /* 2. Anyone may modify your copy or copies of SGML parser source code or
- /* any portion of it, and copy and distribute such modifications provided
- /* that all modifications are clearly associated with the entity that
- /* performs the modifications.
- /*
- /* NO WARRANTY
- /* ===========
- /*
- /* NIST PROVIDES ABSOLUTELY NO WARRANTY. THE SGML PARSER AND VALIDATION
- /* SUITE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- /* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- /* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
- /* WITH YOU. SHOULD THE SGML PARSER OR VALIDATION SUITE PROVE DEFECTIVE,
- /* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- /*
- /* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NIST BE LIABLE FOR
- /* DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
- /* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- /* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- /* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
- /* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
- /* NIST) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
- /* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- */
-
- /************************************************************************/
- /* TITLE: SGML PARSER */
- /* SYSTEM: DTD PROCESSOR */
- /* SUBSYSTEM: */
- /* SOURCE FILE: DTDSUTIL.C */
- /* AUTHOR: Michael Garris */
- /* */
- /* DATE CREATED: */
- /* LAST MODIFIED: */
- /* */
- /* REVISIONS */
- /* WHEN WHO WHY */
- /************************************************************************/
- #include <stdio.h>
- #include <setjmp.h>
- #include "qntyset.h"
- #include "dtd.h"
- #include "dtdfncs.h"
- #include "dtddefs.h"
- #include "dtdglbl.h"
- /************************************************************************/
- /* globals for linked list used for resolving entity references */
- /************************************************************************/
- static SYMBOL Nsymbol; /* structure containing:
- name, syntactic literal, parameter literal */
-
-
- static NODE *Phead = NULL;/* pointer to first NODE in parameter entity
- linked list, initialized to NULL */
-
- static NODE *Ghead = NULL;/* pointer to first NODE in general entity
- linked list, initialized to NULL */
-
- /************************************************************************/
- /* doentity() is the main module for processing any entity declaration. */
- /* It calls routines to input PS's, get the entity name, and get the */
- /* entity text building 2 pairs of tables, 1 (parameter entity, general */
- /* entity) pair as linked lists, and the second (parameter entity, */
- /* general entity) pair as output to file. */
- /************************************************************************/
- void doentity()
- {
- char *nameptr, *litptr;
- int synkey;
- int pscount;
- int enttype;
- int c;
-
- pscount = INPPS();
- nameptr = getentname(pscount, &enttype);
- pscount = INPPS();
- synkey = getenttext(pscount, &litptr, enttype);
- pscount = INPPS();
- ADDCHAR(SPACE);
- if((c = jgetc()) == EOF)
- terminate(1, "End of File found while expecting MDO");
- if(c == MDC) {
- buildtbl(enttype, nameptr, synkey, litptr);
- ADDCHAR(MDC);
- }
- else{
- ADDCHAR(c);
- jungetc(c);
- syntxerr("MDC not found in entity declaration");
- }
- }
-
- /************************************************************************/
- /* getentname() gets a valid entity name determining if the name is a */
- /* valid general entity name or a valid parameter entity name. */
- /************************************************************************/
- char *getentname(pscount, typeptr)
- int pscount;
- int *typeptr;
- {
- static char namearray[NAMELEN + 1], *nptr;
- int c, j;
-
- nptr = namearray;
- if((c = jgetc()) == EOF)
- terminate(1, "EOF found");
- if(c != PERO){
- /* then general entity declaration */
- *typeptr = GEN_ENT_NAME;
- if(pscount == 0)
- syntxerr("Required PS not found");
- jungetc(c);
- j = INPRNINAME( &nptr, NAMELEN, noxlat);
- if (namearray[0] == RNI)
- if(strcmp(namearray, "#DEFAULT") != 0){
- ADDCHAR(SPACE);
- ADDSTRING(namearray);
- syntxerr("Illegal use of RNI in entity name");
- }
- }
- else{
- /* else parameter entity declaration */
- *typeptr = PARM_ENT_NAME;
- ADDCHAR(SPACE);
- ADDCHAR(PERO);
- if(INPPS() >= 1)
- j = INPNAME( &nptr, NAMELEN - 1, noxlat);
- else
- syntxerr("Required PS not found in parameter entity name");
- }
- ADDCHAR(SPACE);
- ADDSTRING(namearray);
- if(j >= GOOD)
- return(namearray);
- else
- syntxerr("Entity name not found");
- /* should not be reached, only for lint */
- return(namearray);
- }
-
- /************************************************************************/
- /* getenttext() gets the entity text for any entity declaration. It */
- /* inputs a syntactic literal which may be NULL, PS's, and a parameter */
- /* literal. */
- /************************************************************************/
- int getenttext(pscount, litptr, enttype)
- int pscount;
- char **litptr;
- int enttype;
- {
- char namearray[NAMELEN + 1], *nameptr = namearray;
- static char litarray[LITLEN + 1];
- char *lptr;
- int j, jj, synlitsize;
-
- lptr = litarray;
- memset(litarray, '\0', LITLEN);
- if((j = INPNAME(&nameptr, NAMELEN, TOUPPER)) == EOF)
- terminate(1, "EOF found in entity declaration");
- switch (j){
-
- case KW_SYSTEM:
- case KW_PUBLIC:
- if(pscount < 1)
- syntxerr("PS not found before syntactic literal in data text");
- ADDCHAR(SPACE);
- ADDSTRING(synliteral(j));
- ADDCHAR(SPACE);
- /* call procedure to input the parameter literal */
- if (j == KW_SYSTEM)
- dosystem(YES);
- else dopublic(YES);
- if (INPPS() == EOF)
- terminate(1, "EOF found in entity declaration");
- ADDCHAR(SPACE);
- nameptr = namearray;
- if((jj = INPNAME(&nameptr, NAMELEN, TOUPPER)) == EOF)
- terminate(1, "EOF found in entity declaration");
- if (jj < GOOD)
- return(j);
- ADDSTRING(namearray);
- if (jj != KW_NDATA)
- syntxerr("illegal syntactic keyword");
- else if (enttype != GEN_ENT_NAME)
- syntxerr("General entity name required when using entity type");
- if (INPPS() == EOF)
- terminate(1, "EOF found in entity declaration");
- nameptr = litarray;
- if((jj = INPNAME(&nameptr, NAMELEN, TOUPPER)) == EOF)
- terminate(1, "EOF found in entity declaration");
- if (jj < GOOD)
- syntxerr("expected NOTATION NAME");
- *litptr = litarray;
- return(j);
- /* cases for DATA TEXT */
- case KW_CDATA:
- case KW_SDATA:
- /* CDATA and SDATA may only be used with in a general entity decl */
- if(enttype == PARM_ENT_NAME){
- ADDCHAR(SPACE);
- ADDSTRING(synliteral(j));
- syntxerr("Illegal use of data text while processing entity text");
- }
- case KW_PI:
- if(pscount < 1)
- syntxerr("PS not found before syntactic literal in data text");
- ADDCHAR(SPACE);
- ADDSTRING(synliteral(j));
- if (INPPS() == EOF)
- terminate(1, "EOF found in entity declaration");
- ADDCHAR(SPACE);
- /* call procedure to input the parameter literal */
- inpparmlit(&lptr);
- *litptr = litarray;
- /* return the syntactic literal */
- return(j);
-
- /* cases for BRAKETED TEXT */
- case KW_STARTTAG:
- synlitsize = STARTTAGSIZE;
- goto SHARE;
- case KW_ENDTAG:
- synlitsize = ENDTAGSIZE;
- goto SHARE;
- case KW_MS:
- synlitsize = MSSIZE;
- goto SHARE;
- case KW_MD:
- synlitsize = MDSIZE;
- SHARE:
- if(pscount < 1)
- syntxerr("PS not found before syntactic literal in braketed text");
- ADDCHAR(SPACE);
- ADDSTRING(synliteral(j));
- INPPS();
- ADDCHAR(SPACE);
- /* call procedure to input parameter literal */
- inpparmlit(&lptr);
- *litptr = litarray;
- /* if the length of the parameter literal plus the length of */
- /* the corresponding bracketed text delimeters exceeds LITLEN */
- /* then ERROR */
- if((synlitsize + strlen(litarray)) > LITLEN)
- syntxerr("LITLEN exceeded in interpreted bracketed text.");
- /* return the syntactic literal */
- return(j);
- /* If BAD name, ie. NULL syntactice literal, then check if */
- /* there exists a parameter literal */
- case BAD:
- if((j = jgetc()) == EOF)
- terminate(1, "End of File found while processing entity text");
- /* if a parameter literal does not exist then ERROR */
- if((j != LITA) && (j != LIT)){
- ADDCHAR(j);
- jungetc(j);
- syntxerr("Entity text not found");
- }
- jungetc(j);
- ADDCHAR(SPACE);
- /* else call procedure to input parameter literal */
- inpparmlit(&lptr);
- *litptr = litarray;
- return(NULL);
- default:
- /* syntactic literal found out of context */
- ADDCHAR(SPACE);
- ADDSTRING(synliteral(j));
- syntxerr("Entity text not found");
- }
- /*should never be reached, for lint only*/
- return(BAD);
- }
-
- /************************************************************************/
- /* search() determines the type of a name passed (parameter, general) */
- /* and searches through the appropriate linked list for a match on the */
- /* name. If the name is found, it returns the syntactic literal and */
- /* parameter literal text. Otherwise, if the name is not found or the */
- /* list is empty, the procedure returns an error flag value. */
- /************************************************************************/
- int search(enttype, nptr, litptr)
- int enttype;
- char *nptr, **litptr;
- {
- NODE *Ncurrptr;
- NODE *head;
- char *lptr = *litptr;
-
- mprintf("Entered [search].\n");
- /* if entity name being searched for is a parameter entity name ... */
- if(enttype == PARM_ENT_NAME)
- /* search the parameter entity linked list */
- head = Phead;
- else
- /* else the name is a general entity name, so search the general */
- /* entity linked list. */
- head = Ghead;
- /* if linked list is not empty ... */
- if(head != NULL){
- Ncurrptr = head;
- /* while no match on name and not at end of linked list ... */
- while((strcmp(nptr, Ncurrptr -> Nsymbol.SSname) != 0)
- && (Ncurrptr -> Nnextptr != NULL))
- Ncurrptr = Ncurrptr -> Nnextptr;
- /* if match on name ... */
- if(strcmp(nptr, Ncurrptr -> Nsymbol.SSname) == 0){
- lptr = Ncurrptr -> Nsymbol.Sdef;
- *litptr = lptr;
- return(Ncurrptr -> Nsymbol.Ssynkey);
- }
- }
- /* else either linked list empty or name not found in list */
- *litptr = lptr;
- /* so return error flag */
- return(ILLCHAR);
- }
-
- /************************************************************************/
- /* buildtbl() determines what type of entity name is passed and adds a */
- /* new node to the appropriate linked list and calls a procedure which */
- /* adds a record of info to the appropriate file table. */
- /************************************************************************/
- void buildtbl(enttype, nameptr, synkey, litptr)
- int enttype, synkey;
- char *nameptr, *litptr;
- {
- NODE *Nnode, *Ncurrptr;
- char *malloc();
- NODE **headptr;
-
- /* if parameter entity name, then use parameter entity linked list */
- if(enttype == PARM_ENT_NAME)
- headptr = &Phead;
- else
- /* else use the general entity linked list */
- headptr = &Ghead;
- mprintf("Entered [buildtbl].\n");
- /* allocate memory for a new NODE */
- Nnode = (NODE *)(malloc(sizeof(NODE)));
- if(Nnode == 0)
- terminate(1, "Unable to allocate memory using malloc");
- /* set the node pointer in Nnode to NULL because it will added to the */
- /* end of the existing linked list */
- Nnode -> Nnextptr = NULL;
- mprintf("Calling [buildsymbol] from [buildtbl].\n");
- /* call procedure which adds to the appropriate file table and */
- /* sets up Nnode with valid data */
- buildandwritesymbol(enttype, &(Nnode -> Nsymbol), nameptr, synkey, litptr);
- /* if the list is empty, then simply make */
- /* Nnode the first node in the list */
- if(*headptr == NULL)
- *headptr = Nnode;
- else{
- /* else search the appropriate linked list to the end of the list */
- Ncurrptr = *headptr;
- while(Ncurrptr -> Nnextptr != NULL)
- Ncurrptr = Ncurrptr -> Nnextptr;
- /* and add Nnode to the end of the list */
- Ncurrptr -> Nnextptr = Nnode;
- }
- mprintf("Exiting [buildtbl].\n");
- }
-
- /************************************************************************/
- /* buildandwritesymbol() is a procedure which updates the appropriate */
- /* file table according to whether the entity name is a parameter or */
- /* general entity name. It also fills the node which is to be added to */
- /* the appropriate linked list with proper data. */
- /************************************************************************/
- void buildandwritesymbol(enttype, symbol, nameptr, synkey, litptr)
- int enttype;
- SYMBOL *symbol;
- char *nameptr;
- int synkey;
- char *litptr;
- {
- int litlen,i;
- char namebuff[NAMELEN];
- char *nptr,*namebuffptr;
-
- mprintf("Entered [buildsymbol].\n");
- nptr = nameptr;
- namebuffptr = namebuff;
- /* put the name passed into a buffer which is right padded with spaces */
- for(i = 0; i < NAMELEN; ++i)
- *namebuffptr++ = ' ';
- namebuffptr = namebuff;
- while(*nptr != '\0')
- *namebuffptr++ = *nptr++;
-
- litlen = strlen(litptr) + 1;
- /* call procedure which actually writes the data to the appropriate file */
- writerecord(enttype, namebuff, synkey, litptr, litlen);
- /* copy the entity name into a node to be added to the linked list */
- strcpy (symbol->SSname, nameptr);
- /* copy the syntactic literal into the node to be added */
- symbol -> Ssynkey = synkey;
- /* copy the parameter literal ext into the node */
- strcpy (symbol -> Sdef, litptr);
- mprintf("Exiting [buildsymbol].\n");
- }
-
- /********************************************************************/
- /* writerecord() writes a record of data into the appropriate file */
- /* table using a procedure called safewrite. */
- /********************************************************************/
- void writerecord(enttype, nameptr, synkey, litptr, litlen)
- int enttype;
- char *nameptr, *litptr;
- int synkey, litlen;
- {
- int file;
-
- /* if entity a parameter entity then use parameter entity file table */
- if(enttype == PARM_ENT_NAME)
- file = preffile;
- else
- /* else use the general entity file table */
- file = greffile;
- /* first field = length of parameter literal text */
- safewrite(file,(char *)&litlen,sizeof(litlen));
- /* second field = entity name */
- safewrite(file, nameptr, (unsigned)(NAMELEN));
- /* third field = syntactic literal */
- safewrite(file,(char *)&synkey, sizeof(synkey));
- /* fourth field = parameter literal text */
- safewrite(file, litptr, (unsigned)litlen);
- }
- /* ================================================================ */
-